/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.saashousekeeper.interceptor;

import com.huawei.saashousekeeper.config.TenantContext;
import com.huawei.saashousekeeper.config.adapter.SchemaAdapter;
import com.huawei.saashousekeeper.properties.DataSourceBindingProperty;
import com.huawei.saashousekeeper.properties.DynamicSourceProperties;

import lombok.extern.log4j.Log4j2;

import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.Connection;

/**
 * mybatis拦截，获取connection
 *
 * @since 2022-02-14
 */
@Intercepts( {@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
@Log4j2
public class MybatisInterceptor implements Interceptor {
    @Autowired
    private DynamicSourceProperties dynamicSourceProperties;

    @Autowired
    private SchemaAdapter schemaAdapter;

    @Override
    public Object intercept(Invocation invocation) throws Exception {
        Connection coon = (Connection) invocation.getArgs()[0];
            // 获取传递的租户标识
            String domain = TenantContext.getDomain();
            // 租户标识获取配置的对应schema以及数据源绑定信息
            DataSourceBindingProperty bindingProperty = dynamicSourceProperties.getBindingMap() != null
                    ? dynamicSourceProperties.getBindingMap().getOrDefault(domain, null)
                    : null;
            String catalog = null;
            if (bindingProperty != null && StringUtils.isNotBlank(bindingProperty.getSchema())) {
                // 配置指定的schema, 优先级最高
                catalog = bindingProperty.getSchema();
            } else {
                // 未指定schema, 则使用当前生效的适配器逻辑获取schema, 默认适配器规则为使用
                catalog = schemaAdapter.getSchema(domain);
            }

            if (catalog != null) {
                log.warn("{} select schema {}", domain, catalog);
                coon.setCatalog(catalog);
            }
        return invocation.proceed();
    }
}
